package com.ruoyi.system.service.impl;

import java.util.*;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.enums.CrawlerStatusType;
import com.ruoyi.common.enums.CustomerType;
import com.ruoyi.common.enums.ImportType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.from.CrmCustomerAdd;
import com.ruoyi.system.domain.from.CrmCustomerInfoQuery;
import com.ruoyi.system.domain.from.CrmCustomerUpdate;
import com.ruoyi.system.domain.from.DeleteList;
import com.ruoyi.system.domain.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.CrmCustomerInfoMapper;
import com.ruoyi.system.service.ICrmCustomerInfoService;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;

/**
 * @author yangsen
 * @date 2023-05-10
 */
@Slf4j
@Service
public class CrmCustomerInfoServiceImpl extends ServiceImpl<CrmCustomerInfoMapper, CrmCustomerInfo> implements ICrmCustomerInfoService {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    private CrmCustomerInfoMapper crmCustomerInfoMapper;




    private static String baseAreaConfig = "baseArea";
    private static String baseCityConfig = "baseCity";
    private static String baseProvinceConfig = "baseProvince";

    /**
     * 查询客户
     *
     * @return 客户
     * @paramcustomerId 客户主键
     */
    @Override
    public R<CrmCustomerInfoDetail> selectCrmCustomerInfoBycustomerId(Long customerId) {
        CrmCustomerInfo crmCustomerInfo = getById(customerId);
        if (ObjectUtil.isNull(crmCustomerInfo)) {
            return R.fail("客户信息不存在");
        }
        List<Long> codeList = new ArrayList<>();
        codeList.add(crmCustomerInfo.getProvinceCode());
        codeList.add(crmCustomerInfo.getCityCode());
        codeList.add(crmCustomerInfo.getDistrictCode());
        CrmCustomerInfoDetail crmCustomerInfoDetail = CrmCustomerInfoDetail.builder()
                .customerId(crmCustomerInfo.getCustomerId())
                .codeList(codeList)
                .companyName(crmCustomerInfo.getCompanyName())
                .build();
        return R.ok(crmCustomerInfoDetail);
    }

    /**
     * 查询客户列表
     *
     * @param crmCustomerInfoQuery 客户
     * @return 客户
     */
    @Override
    @DataScope(deptAlias = "d",userAlias = "u")
    public R<CustomerInfoPageVo> selectCrmCustomerInfoList(CrmCustomerInfoQuery crmCustomerInfoQuery, String customerType) {
        crmCustomerInfoQuery.setCustomerType(customerType);
        Page<CrmCustomerInfo> page =new Page<>(crmCustomerInfoQuery.getCurrent(),crmCustomerInfoQuery.getSize());
        IPage<CrmCustomerInfo> crmCustomerInfoIPage = crmCustomerInfoMapper.selectByPage(page, crmCustomerInfoQuery);
        List<CustomerInfoPageListVo> CustomerInfoPageListVos = new ArrayList<>();
        for (CrmCustomerInfo record : crmCustomerInfoIPage.getRecords()) {
            CustomerInfoPageListVo infoPageListVo = CustomerInfoPageListVo.builder()
                    .companyName(record.getCompanyName())
                    .customerId(record.getCustomerId())
                    .createBy(record.getCreateBy())
                    .address(record.getProvinceName() + " " + record.getCityName() + " " + record.getDistrictName())
                    .fileName(record.getFileName())
                    .importFlag(record.getImportFlag())
                    .insuredPopulation(record.getInsuredPopulation())
                    .qualifiedFollowers(record.getQualifiedFollowers())
                    .outPoverty(record.getOutPoverty())
                    .unemPloyment(record.getUnemPloyment())
                    .deductionPloyment(record.getDeductionPloyment())
                    .refundPart(record.getRefundPart())
                    .refundOutPart(record.getRefundOutPart())
                    .refundRetiredPart(record.getRefundRetiredPart())
                    .deductionPart(record.getDeductionPart())
                    .deductionOutPart(record.getDeductionOutPart())
                    .deductionRetiredPart(record.getDeductionRetiredPart())
                    .dataProcessing(record.getDataProcessing())
                    .eligiblePersons(record.getEligiblePersons())
                    .septemberSocial(record.getSeptemberSocial())
                    .crawlerStatus(record.getCrawlerStatus()).build();
            CustomerInfoPageListVos.add(infoPageListVo);
        }
        CustomerInfoPageVo infoPageVo = CustomerInfoPageVo.builder().size(crmCustomerInfoIPage.getSize())
                .current(crmCustomerInfoIPage.getCurrent())
                .total(crmCustomerInfoIPage.getTotal())
                .records(CustomerInfoPageListVos)
                .build();
        return R.ok(infoPageVo);
    }

    /**
     * 全量导出
     *
     * @param
     * @return 客户
     */
    @Override
    public void exportCrmCustomerInfo(HttpServletResponse response, String customerType, CrmCustomerInfoQuery crmCustomerInfoQuery) {
        QueryWrapper<CrmCustomerInfo> lambdaQueryWrapper;
        if (!this.roleList()) {
            lambdaQueryWrapper = new QueryWrapper<CrmCustomerInfo>()
                    .eq("create_id", SecurityUtils.getUserId())
                    .eq("customer_type", customerType)
                    .orderByDesc("create_time");
        } else {
            lambdaQueryWrapper = new QueryWrapper<CrmCustomerInfo>()
                    .eq("customer_type", customerType)
                    .orderByDesc("create_time");
        }
        if (StringUtils.isNotNull(crmCustomerInfoQuery.getProvinceName()))
            lambdaQueryWrapper.like("province_name", crmCustomerInfoQuery.getProvinceName());
        if (crmCustomerInfoQuery.getImportFlag() != null)
            lambdaQueryWrapper.eq("import_flag", crmCustomerInfoQuery.getImportFlag());
        if (StringUtils.isNotNull(crmCustomerInfoQuery.getCompanyName()))
            lambdaQueryWrapper.eq("company_name", crmCustomerInfoQuery.getCompanyName());

        List<CrmCustomerInfo> crmCustomerInfos = list(lambdaQueryWrapper);
        List<CrmCustomerInfoExportVo> crmCustomerInfoExportVos = new ArrayList<>();
        CustomerType byCode = CustomerType.getByCode(customerType);
        String customerTypeMessage;
        if (ObjectUtil.isNull(byCode)) {
            log.error("客户类型被删除");
            customerTypeMessage = "";
        } else {
            customerTypeMessage = byCode.getCustomerTypeMessage();
        }
        Integer i = 1;
        for (CrmCustomerInfo crmCustomerInfo : crmCustomerInfos) {
            crmCustomerInfoExportVos.add(CrmCustomerInfoExportVo
                    .builder()
                    .sort(i)
                    .createBy(crmCustomerInfo.getCreateBy())
                    .companyAddress(crmCustomerInfo.getProvinceName() + " " + crmCustomerInfo.getCityName() + " " + crmCustomerInfo.getDistrictName())
                    .companyName(crmCustomerInfo.getCompanyName())
                    .customerType(customerTypeMessage)
                    .insuredPopulation(crmCustomerInfo.getInsuredPopulation())
                    .qualifiedFollowers(crmCustomerInfo.getQualifiedFollowers())
                    .outPoverty(crmCustomerInfo.getOutPoverty())
                    .unemPloyment(crmCustomerInfo.getUnemPloyment())
                    .refundPart(crmCustomerInfo.getRefundPart())
                    .deductionPart(crmCustomerInfo.getDeductionPart())
                    .build());
            i += 1;
        }
        ExcelUtil<CrmCustomerInfoExportVo> util = new ExcelUtil<CrmCustomerInfoExportVo>(CrmCustomerInfoExportVo.class);
        util.exportExcel(response, crmCustomerInfoExportVos, customerTypeMessage);
    }


    private Boolean roleList() {
        List<SysRole> roles = SecurityUtils.getLoginUser().getUser().getRoles();
        boolean bool = false;
        if (ObjectUtil.isNull(roles) && roles.size() == 0) {
            return bool;
        }
        for (SysRole role : roles) {
            if ("admin".equals(role.getRoleKey())) {
                bool = true;
            }
        }
        return bool;
    }


    /**
     * 批量删除客户
     *
     * @return 结果
     * @paramcustomerIds 需要删除的客户主键
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult deleteCrmCustomerInfoBycustomerIds(Long customerId) {
//        iCrmCustomerUserService.remove(new QueryWrapper<CrmCustomerUserInfo>().eq("customer_id", customerId));;
        //TODO 其他删除
        return AjaxResult.success(this.removeById(customerId));
    }

    @Override
    public AjaxResult deleteCrmCustomerInfoBycustomerIdsAll(DeleteList deleteList) {
        for (Long customerId : deleteList.getCustomerIds()) {
            this.deleteCrmCustomerInfoBycustomerIds(customerId);
        }
        return AjaxResult.success();
    }

    /**
     * 新增客户
     *
     * @param crmCustomerAdd 客户
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addCrmCustomerInfo(CrmCustomerAdd crmCustomerAdd,String customerType) {
        Map<String, SysRegion> baseAreaMap = (Map<String, SysRegion>) redisTemplate.opsForValue().get(baseAreaConfig);
        Map<String, SysRegion> baseCityMap = (Map<String, SysRegion>) redisTemplate.opsForValue().get(baseCityConfig);
        Map<String, SysRegion> baseProvinceMap = (Map<String, SysRegion>) redisTemplate.opsForValue().get(baseProvinceConfig);
        if (ObjectUtil.isNull(baseAreaMap) || ObjectUtil.isNull(baseCityMap) || ObjectUtil.isNull(baseProvinceMap)) {
            throw new RuntimeException("获取省 市 区异常");
        }
        if (ObjectUtil.isNull(baseAreaMap.get(crmCustomerAdd.getCodeList().get(2)))
                || ObjectUtil.isNull(baseCityMap.get(crmCustomerAdd.getCodeList().get(1)))
                || ObjectUtil.isNull(baseProvinceMap.get(crmCustomerAdd.getCodeList().get(0)))) {
            return AjaxResult.error("省 市 区 编码错误");
        }
        CrmCustomerInfo customerInfo = CrmCustomerInfo.builder()
                .companyName(crmCustomerAdd.getCompanyName())
                .provinceName(baseProvinceMap.get(crmCustomerAdd.getCodeList().get(0)).getName())
                .provinceCode(crmCustomerAdd.getCodeList().get(0))
                .cityName(baseCityMap.get(crmCustomerAdd.getCodeList().get(1)).getName())
                .cityCode(crmCustomerAdd.getCodeList().get(1))
                .districtName(baseAreaMap.get(crmCustomerAdd.getCodeList().get(2)).getName())
                .districtCode(crmCustomerAdd.getCodeList().get(2))
                .createId(SecurityUtils.getUserId())
                .dataProcessing(ImportType.TOBEIMPROTINGDATA.getImprotTypeCode())
                .customerType(customerType)
                .crawlerStatus(CrawlerStatusType.NORMAL.getCrawlerStatusTypeCode())
                .deptId(SecurityUtils.getDeptId())
                .build();
        customerInfo.setCreateBy(SecurityUtils.getUsername());
        customerInfo.setCreateTime(new Date());
        return AjaxResult.success(this.save(customerInfo));
    }

    /**
     * 修改客户
     *
     * @return 结果
     * @crmCustomerUpdate
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult updateCrmCustomerInfoNew(CrmCustomerUpdate crmCustomerUpdate) {
        CrmCustomerInfo crmCustomerInfo = getById(crmCustomerUpdate.getCustomerId());
        if (ObjectUtil.isNull(crmCustomerInfo)) {
            return AjaxResult.error("客户信息不存在");
        }
        Map<String, SysRegion> baseAreaMap = (Map<String, SysRegion>) redisTemplate.opsForValue().get(baseAreaConfig);
        Map<String, SysRegion> baseCityMap = (Map<String, SysRegion>) redisTemplate.opsForValue().get(baseCityConfig);
        Map<String, SysRegion> baseProvinceMap = (Map<String, SysRegion>) redisTemplate.opsForValue().get(baseProvinceConfig);
        if (ObjectUtil.isNull(baseAreaMap) || ObjectUtil.isNull(baseCityMap) || ObjectUtil.isNull(baseProvinceMap)) {
            throw new RuntimeException("获取省 市 区异常");
        }
        if (ObjectUtil.isNull(baseAreaMap.get(crmCustomerUpdate.getCodeList().get(2)))
                || ObjectUtil.isNull(baseCityMap.get(crmCustomerUpdate.getCodeList().get(1)))
                || ObjectUtil.isNull(baseProvinceMap.get(crmCustomerUpdate.getCodeList().get(0)))) {
            return AjaxResult.error("省 市 区 编码错误");
        }
        CrmCustomerInfo customerInfo = CrmCustomerInfo.builder()
                .customerId(crmCustomerUpdate.getCustomerId())
                .companyName(crmCustomerUpdate.getCompanyName())
                .provinceName(baseProvinceMap.get(crmCustomerUpdate.getCodeList().get(0)).getName())
                .provinceCode(crmCustomerUpdate.getCodeList().get(0))
                .cityName(baseCityMap.get(crmCustomerUpdate.getCodeList().get(1)).getName())
                .cityCode(crmCustomerUpdate.getCodeList().get(1))
                .districtName(baseAreaMap.get(crmCustomerUpdate.getCodeList().get(2)).getName())
                .districtCode(crmCustomerUpdate.getCodeList().get(2))
                .build();
        customerInfo.setUpdateBy(SecurityUtils.getUsername());
        customerInfo.setUpdateTime(new Date());
        return AjaxResult.success(updateById(customerInfo));
    }

    /**
     * 转换客户
     *
     * @return 结果
     * @customerId 客户ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult exchangeCrmCustomerInfo(Long customerId) {
        CrmCustomerInfo crmCustomerInfo = getById(customerId);
        if (ObjectUtil.isNull(crmCustomerInfo)) {
            return AjaxResult.error("客户信息不存在");
        }
        if (CustomerType.INTENDEDCUSTOMERS.getCustomerTypeCode().equals(crmCustomerInfo.getCustomerType())) {
            crmCustomerInfo.setCustomerType(CustomerType.CONTRACTEDCUSTOMERS.getCustomerTypeCode());
            crmCustomerInfo.setDataProcessing(ImportType.TOBEIMPROTINGDATA.getImprotTypeCode());
        } else {
            crmCustomerInfo.setCustomerType(CustomerType.INTENDEDCUSTOMERS.getCustomerTypeCode());
        }
        return AjaxResult.success(updateById(crmCustomerInfo));
    }

    @Override
    public AjaxResult realTime(Long customerId) {
        CrmCustomerInfo crmCustomerInfo = getById(customerId);
        if (ObjectUtil.isNull(crmCustomerInfo)) {
            return AjaxResult.error("客户信息不存在");
        }
        List<RealTimeVo> realTimeVos=new ArrayList<>();
        //失业金额计算
        String replaced =String.format("2019~2023年：失业人口：%s人，金额：%s元（仅为做过失业登记，且持有就业创业证人员，还未进行登记6个月以上数据比对。）",crmCustomerInfo.getUnemPloyment() , (crmCustomerInfo.getRefundOutPart()+ crmCustomerInfo.getDeductionOutPart())*650);
        RealTimeVo realTimeVo = RealTimeVo.builder().id(1).message(replaced).build();
        realTimeVos.add(realTimeVo);
        //脱贫人口
        String outPoverAmountReplaced =String.format("2019~2023年：脱贫人口：%s人，金额：%s元  ",crmCustomerInfo.getOutPoverty() , (crmCustomerInfo.getRefundPart()+ crmCustomerInfo.getDeductionPart())*650);
        RealTimeVo realTimeVo1 = RealTimeVo.builder().id(2).message(outPoverAmountReplaced).build();
        realTimeVos.add(realTimeVo1);
        //退伍军人
        String refundRetireAmountReplaced =String.format("2019~2023年：退伍军人：%s人，金额：%s元  ",crmCustomerInfo.getDeductionPloyment() , (crmCustomerInfo.getRefundRetiredPart()+ crmCustomerInfo.getDeductionRetiredPart())*750);
        RealTimeVo realTimeVo2 = RealTimeVo.builder().id(3).message(refundRetireAmountReplaced).build();
        realTimeVos.add(realTimeVo2);
        //2023年9月份可申请社保补贴预估金额
        String SeptemberSocial =String.format("2023年9月份可申请社保补贴预估金额：%s元 ",crmCustomerInfo.getSeptemberSocial() * 1072);
        RealTimeVo realTimeVo3 = RealTimeVo.builder().id(4).message(SeptemberSocial).build();
        realTimeVos.add(realTimeVo3);
        //合同总参保人数
        String insuredPopulation =String.format("合同总参保人数%s人",crmCustomerInfo.getInsuredPopulation());
        RealTimeVo realTimeVo4 = RealTimeVo.builder().id(5).message(insuredPopulation).build();
        realTimeVos.add(realTimeVo4);
        return AjaxResult.success(realTimeVos);
    }


}
